#include "thread_pool.hpp"
extern ListNode *userList;
// goto语句有问题
void handleMessage(int sockfd, int epfd, task_queue_t *queue)
{
    int length = -1;
    int ret = recvn(sockfd, &length, sizeof(length));
    if (ret == 0)
    {
        // goto end;
    }
    printf("\n\nrecv length: %d\n", length);
    int cmdType = -1;
    ret = recvn(sockfd, &cmdType, sizeof(cmdType));
    if (ret == 0)
    {
        // goto end;
    }
    printf("recv cmd type: %d\n", cmdType);
    task_t *ptask = (task_t *)calloc(1, sizeof(task_t));
    ptask->epfd = epfd;
    ptask->peerfd = sockfd;
    ptask->type = (CmdType)cmdType;
    if (length > 0)
    {
        ret = recvn(sockfd, ptask->data, length);
        if (ret > 0)
        {
            if (ptask->type == CMD_TYPE_PUTS)
            {
                epollDelReadFd(epfd, sockfd);
            }
            taskEnqueue(queue, ptask);
        }
    }
    else if (length == 0)
    {
        taskEnqueue(queue, ptask);
    }
    // end:
    //     if (ret == 0)
    //     { // 连接断开的情况
    //         printf("\nconn %d is closed.\n", sockfd);
    //         epollDelReadFd(epfd, sockfd);
    //         close(sockfd);
    //         deleteNode2(&userList, sockfd); // 删除用户信息}
    //     }
}
void doTask(task_t *task)
{
    assert(task);
    switch (task->type)
    {
    case CMD_TYPE_PWD:
        pwdCommand(task);
        break;
    case CMD_TYPE_CD:
        cdCommand(task);
        break;
    case CMD_TYPE_LS:
        lsCommand(task);
        break;
    case CMD_TYPE_MKDIR:
        mkdirCommand(task);
        break;
    case CMD_TYPE_RMDIR:
        rmdirCommand(task);
        break;
    case CMD_TYPE_NOTCMD:
        notCommand(task);
        break;
    case CMD_TYPE_PUTS:
        putsCommand(task);
        break;
    case CMD_TYPE_GETS:
        getsCommand(task);
        break;
    case LOGIN_PRE:
        userLoginCheck1(task);
        break;
    case LOGIN_Q:
        userLoginCheck1(task);
        break;
    case REGISTER_PRE:
        userRegistCheck2(task);
        break;
    case REGISTER_Q:
        userRegistCheck2(task);
        break;
    }
}
void lsCommand(task_t *task)
{
    ListNode *pNode = userList;
    while (pNode != nullptr)
    {
        user_info_t *user = (user_info_t *)pNode->val;
        if (user->sockfd == task->peerfd)
        {
            train_t t;
            char ret[300] = {0};
            string ls;
            DIR *dir = opendir(task->data);
            struct dirent *curr;
            // memset(curr, 0, sizeof(curr));
            while ((curr = readdir(dir)) != nullptr)
            {
                if (strcmp(curr->d_name, ".") == 0 || strcmp(curr->d_name, "..") == 0)
                {
                    continue;
                }
                sprintf(ret, "%s ", curr->d_name);
                ls += ret;
            }
            t.len = ls.size() + 1;
            strncpy(t.buff, ls.c_str(), t.len);
            t.type = CMD_TYPE_LS;
            sendn(task->peerfd, &t, 8 + t.len);
            return;
        }
        pNode = pNode->next;
    }
    // printf("execute ls command.\n");
}
void pwdCommand(task_t *task)
{
    printf("execute pwd command.\n");
}
void cdCommand(task_t *task)
{
    printf("execute cd command.\n");
}

void mkdirCommand(task_t *task)
{
    printf("execute mkdir command.\n");
}

void rmdirCommand(task_t *task)
{
    printf("execute rmdir command.\n");
}

void notCommand(task_t *task)
{
    printf("execute not command.\n");
}

void getsCommand(task_t *task)
{
    printf("execute gets command.\n");
}
void putsCommand(task_t *task)
{
    printf("execute puts command.\n");
    char filename[20] = {0};
    strcpy(filename, task->data);
    printf("filname: %s\n", filename);
    off_t filesize;
    memset(&filesize, 0, sizeof(filesize));
    int ret = recvn(task->peerfd, &filesize, sizeof(filesize));
    printf("filelen: %ld.\n", filesize);
    int fd = open(filename, O_CREAT | O_RDWR, 0644);
    if (fd < 0)
    {
        perror("open");
        return;
    }
    off_t cur = filesize;
    char buffer[1000] = {0};
    while (cur > 0)
    {
        memset(buffer, 0, sizeof(buffer));
        if (cur < 1000)
        {
            ret = recvn(task->peerfd, buffer, cur);
        }
        else
        {
            ret = recvn(task->peerfd, buffer, sizeof(buffer));
        }
        if (ret < 0)
        {
            break;
        }
        ret = write(fd, buffer, ret);
        cur -= ret;
    }
    close(fd);
    epollAddReadFd(task->epfd, task->peerfd);
}
void userLoginCheck1(task_t *task)
{
    printf("userLoginCheck1.\n");
    ListNode *pNode = userList;
    while (pNode != nullptr)
    {
        user_info_t *user = (user_info_t *)pNode->val;
        if (user->sockfd == task->peerfd)
        {
            // strcpy(user->name, task->data);
            loginCheck1(user, task);
            return;
        }
        pNode = pNode->next;
    }
}
void userRegistCheck2(task_t *task)
{
    printf("userLoginCheck2.\n");
    ListNode *pNode = userList;
    while (pNode != nullptr)
    {
        user_info_t *user = (user_info_t *)pNode->val;
        if (user->sockfd == task->peerfd)
        {
            registCheck2(user, task->data, task);
            return;
        }
        pNode = pNode->next;
    }
}